Skip to content

feat: define Slurm config and plan contracts - #879

Open
andreatnvidia wants to merge 7 commits into
feat/slurm-executionfrom
andreatnvidia/feat/slurm-config-plan-contracts
Open

feat: define Slurm config and plan contracts#879
andreatnvidia wants to merge 7 commits into
feat/slurm-executionfrom
andreatnvidia/feat/slurm-config-plan-contracts

Conversation

@andreatnvidia

@andreatnvidia andreatnvidia commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

📋 Summary

Defines the strict, versioned authored configuration and immutable resolved-plan boundary for Data Designer Slurm. These contracts give configuration, planning, image, client-worker, and benchmark lanes deterministic shared records without importing Slurm tools or duplicating the runtime/state records in #878.

🔗 Related Issue

Closes #873

Related to #850. Companion to #878, which owns data_designer.slurm.state and the package's direct Pydantic dependency.

🔄 Changes

✨ Added

  • Add strict, frozen authored records for builder input, public invocation settings, client dependencies, MCP providers, deployments, profiles, image operations, and benchmark intent.
  • Accept canonical Data Designer BuilderConfig exports and the public shorthand builder shape.
  • Add deterministic multi-cluster selection with explicit, hostname, and default precedence plus catalog/profile digest validation.
  • Add canonical JSON and SHA-256 contracts for resolved images, dependency locks, placement, topology, shard intent, artifact references, semantic client results, and benchmark manifests/reports.
  • Reject incomplete effective RunConfig payloads instead of applying ambient defaults while loading a plan.
  • Preserve submission validation in resolved plans and require ordered HTTP endpoints per replica lane plus rendezvous claims for multi-node groups.
  • Add cross-record validation for authored config, selected profile, image inspection, dependency lock, Python ABI, image inventory, deployment order, client placement, resource claims, ports, and deterministic floor/remainder sharding.
  • Add sanitized authored, profile, image, dependency, single-node, multi-node, client-result, and benchmark golden records with exact canonical-byte checks.
  • Keep slurm/state/, package metadata, wheel-install scripts, and uv.lock unchanged to avoid overlap with feat: define Slurm runtime and state record contracts #878.

🔍 Attention Areas

⚠️ Reviewers: Please pay special attention to the following:

🧪 Testing

  • .venv/bin/ruff check --fix . && .venv/bin/ruff format .
  • make check-slurm
  • make test-slurm (109 passed)
  • Focused contract suite (106 passed)
  • make test-slurm-wheel-install
  • make test - not run; validation was scoped to the optional Slurm package and isolated wheel boundary.
  • Unit tests added and updated
  • E2E tests - N/A for pure serialized contracts

✅ Checklist

  • Follows commit message conventions
  • Commits are signed off (DCO)
  • Architecture docs updated - N/A; this PR implements the approved F3 boundary in the migration plan

Add strict authored configuration, profile, image, client, benchmark, dependency-lock, and resolved-plan records. Validate cross-record identities and digests with sanitized single-node and multi-node golden fixtures.

Closes #873

Signed-off-by: Andre Manoel <amanoel@nvidia.com>
Signed-off-by: Andre Manoel <amanoel@nvidia.com>
Prevent secret material from entering persisted configuration and make nested contract collections immutable. Tighten client and benchmark semantic invariants with focused negative coverage.

Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
@andreatnvidia
andreatnvidia marked this pull request as ready for review August 20, 2026 17:28
@andreatnvidia
andreatnvidia requested a review from a team as a code owner August 20, 2026 17:28
@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR introduces strict, immutable, versioned contracts for authored Slurm configuration and resolved execution plans.

  • Defines configuration records for builders, invocations, profiles, images, deployments, and benchmarks.
  • Adds deterministic profile selection, canonical serialization and digest contracts, resolved planning records, and cross-record validation.
  • Adds golden serialized records and focused contract tests covering configuration, planning, client results, and benchmark outputs.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported canonical seed-export rejection is fixed by exempting null secret-shaped fields, and a real Hugging Face seed export exercises the corrected path.

Important Files Changed

Filename Overview
packages/data-designer-slurm/src/data_designer/slurm/config/run.py Defines authored run contracts and now accepts canonical Hugging Face seed exports with null token fields while continuing to reject populated secret values.
packages/data-designer-slurm/src/data_designer/slurm/config/profiles.py Defines profile catalogs, deterministic cluster-selection precedence, and digest-bound selected-profile validation.
packages/data-designer-slurm/src/data_designer/slurm/planning/models.py Introduces immutable resolved-plan records for images, dependencies, placement, topology, sharding, and artifacts.
packages/data-designer-slurm/src/data_designer/slurm/planning/validation.py Adds cross-record consistency checks for authored configuration, selected profiles, images, dependencies, placement, resources, and shards.
packages/data-designer-slurm/tests/contracts/test_config_records.py Covers authored contract behavior, including the real canonical Hugging Face seed export associated with the previous review thread.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Authored["Authored Slurm configuration"] --> Validate["Strict contract validation"]
  Catalog["Profile catalog"] --> Select["Deterministic profile selection"]
  Select --> Plan["Immutable resolved plan"]
  Validate --> Plan
  Images["Image inspections and dependency locks"] --> CrossCheck["Cross-record validation"]
  Plan --> CrossCheck
  CrossCheck --> Client["Client execution records"]
  CrossCheck --> Benchmark["Benchmark manifests and reports"]
Loading

Reviews (3): Last reviewed commit: "fix: close Slurm argument validation byp..." | Re-trigger Greptile

Comment thread packages/data-designer-slurm/src/data_designer/slurm/config/run.py

@nabinchha nabinchha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this contract layer together, @andreatnvidia!

Summary

This PR establishes strict authored Slurm configuration, profile/image/client/benchmark records, and immutable resolved-plan records with deterministic serialization and broad cross-record validation. The implementation largely matches the stated intent, but a few boundary gaps still allow persisted secrets or records that are not actually bound to the authored inputs.

Findings

Critical — Let's fix these before merge

packages/data-designer-slurm/src/data_designer/slurm/config/run.py:325 — Secret-bearing vLLM flags can enter persisted config

  • What: validate_extra_args() only rejects flags in _OWNED_VLLM_FLAGS, so a supported vLLM argument such as --hf-token=plaintext-secret is accepted and emitted unchanged by model_dump()/serialize_json().
  • Why: Authored configs and resolved plans are persisted records, so this leaks a bearer token despite the contract's guarantee that secret values are represented only through external references. vLLM explicitly supports --hf-token, making this a reachable path rather than just an arbitrary malformed argument.
  • Suggestion: Apply _is_secret_name() to the normalized option name in extra_args and require those values to come from environment: dict[EnvironmentName, EnvironmentBinding] via SecretRef. Please cover both --hf-token=value and split --hf-token, value forms with negative tests.

packages/data-designer-slurm/src/data_designer/slurm/planning/validation.py:102 — Lock-file mode is not bound to the resolved dependency lock

  • What: Cross-record validation compares authored_requirements only when requirements is not None. When the authored config selects lock_file, neither ResolvedDependencyLock nor validate_resolved_plan() retains or verifies that source lock's identity/digest. I could author locks/user-lock.json, attach the existing golden dependency lock containing data-designer-speech==0.2.0, update the plan's artifact digest, and validate_resolved_plan() still returned successfully.
  • Why: The validated plan may install dependencies unrelated to the lock file the user selected, defeating deterministic dependency resolution and the integrity boundary these records are meant to provide.
  • Suggestion: Bind lock-file mode explicitly—for example, add the authored lock source as an ArtifactReference (or its content digest) to ResolvedDependencyLock, then compare it with the resolved source in validate_resolved_plan(). Add a negative cross-record test where a valid but unrelated lock is substituted.

Warnings — Worth addressing

packages/data-designer-slurm/src/data_designer/slurm/config/profiles.py:217 — Profile provenance is not revalidated

  • What: validate_selected_profile() verifies the catalog digest and selected profile value, but not the claimed selection_source. A record naming the lab profile with selection_source="default" validates even when the catalog's default is primary; similarly, a hostname selection can claim a pattern that is not in the selected profile.
  • Why: Persisted selection provenance can disagree with the deterministic precedence rules while still passing the public validation function, so consumers cannot rely on the record to explain why that cluster was selected.
  • Suggestion: Re-derive the source-specific invariants: require default selections to name catalog.default_cluster, require hostname patterns to belong to the selected profile, and retain enough hostname evidence if the match itself must be replayed. Add forged-default and forged-pattern tests.

packages/data-designer-slurm/src/data_designer/slurm/config/run.py:265 — Requirement validation accepts malformed trailing content

  • What: The non-URL branch uses re.match() without validating the remainder of the string. For example, ClientDependencies(requirements=["not valid !!!"]) is accepted as package not.
  • Why: Invalid authored dependency records survive the strict configuration boundary and fail later in the resolver, where the error is less direct and may occur after other planning work.
  • Suggestion: Parse standard requirements with packaging.requirements.Requirement (while retaining the stricter immutable-wheel rule for direct references), or otherwise full-match the entire supported grammar. Add malformed-suffix and incomplete-version tests.

packages/data-designer-slurm/src/data_designer/slurm/_contracts.py:214 — HTTP URL validation does not require a host

  • What: validate_url() accepts https:///missing-host, and RemoteMCPProviderConfig does not reject the resulting urlsplit(...).hostname is None value.
  • Why: A syntactically invalid MCP endpoint is accepted by the authored contract and only fails when the client attempts to connect.
  • Suggestion: Validate the parsed scheme, hostname, and port (or use Pydantic's HTTP URL type) before applying the no-credentials/query/fragment checks. Add missing-host and invalid-port cases.

What Looks Good

  • The frozen base models, recursive collection freezing, and byte-stable golden records make the process boundary explicit and testable.
  • Placement, topology, ordered port claims, shard ranges, image inspection, and authored/plan digest relationships receive unusually thorough semantic validation.
  • Test coverage is broad and behavior-oriented; the 153 contract tests and changed-file Ruff checks pass cleanly in the isolated review worktree.

Verdict

Needs changes — please close the persisted vLLM-secret path and bind authored lock-file inputs to their resolved lock before merge. The selection-provenance, requirement-parser, and URL-boundary gaps are also worth tightening while these v1 contracts are still being established.


This review was generated by an AI assistant.

Signed-off-by: Andre Manoel <amanoel@nvidia.com>
@andreatnvidia

Copy link
Copy Markdown
Contributor Author

@nabinchha Thanks, these gaps were real. vLLM extra args now reject secret-shaped option names in both equals and split forms, and lock-file mode records an authored source plus a digest-bound ArtifactReference that validate_resolved_plan() binds back to the authored path. I also tightened profile provenance, switched requirement parsing to packaging.requirements.Requirement while retaining the immutable-wheel rules, and require MCP URLs to have a valid host and port. The dependency-lock goldens and plan digests now include the new source fields.

@nabinchha nabinchha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the thoughtful follow-up, @andreatnvidia!

Summary

The new commit addresses the prior review threads around requirement parsing, remote MCP URLs, profile provenance, dependency-lock provenance, secret-shaped vLLM arguments, and canonical builder exports. The implementation now matches the stated contract much more closely, but two validation-boundary gaps remain.

Findings

Critical — Let's fix these before merge

packages/data-designer-slurm/src/data_designer/slurm/config/run.py:196,335 — Combined secret arguments bypass validation

  • What: Both argument validators derive the option name by splitting only on =. As a result, LocalStdioMCPProviderConfig(args=["--api-key sk-123"]) and VllmServerConfig(extra_args=["--api-key sk-123"]) are accepted and preserve the plaintext value in model_dump(). The same form also lets an owned vLLM option such as "--port 9000" bypass _OWNED_VLLM_FLAGS.
  • Why: These authored records are serialized, so the bypass reopens the secret-persistence path this validation is meant to close. It also allows compiler-owned arguments past the contract boundary, where they can fail late or conflict with generated invocation state.
  • Suggestion: Extract the leading option name up to either = or whitespace before applying the owned/secret checks (or reject whitespace-combined option/value entries and require separate argv tokens). Could we add regression coverage for the combined form in both the stdio MCP and vLLM validators?

Warnings — Worth addressing

packages/data-designer-slurm/src/data_designer/slurm/config/run.py:261 — Direct wheel URLs accept invalid ports

  • What: The direct-wheel validator checks parsed.hostname but never accesses parsed.port, so ClientDependencies(requirements=["plugin @ https://example.test:invalid/plugin.whl#sha256=<64 hex chars>"]) is accepted.
  • Why: This lets an invalid URL cross the strict authored-config boundary and fail only during dependency resolution. It is also inconsistent with the updated shared HTTP URL validator, which deliberately evaluates parsed.port and normalizes ValueError.
  • Suggestion: Validate parsed.port inside a try/except ValueError before evaluating the wheel-specific constraints, or reuse the shared URL validation logic. A regression test with a nonnumeric port would lock this down.

What Looks Good

  • The new packaging.Requirement parsing closes the trailing-junk cases and gives normalized duplicate detection a solid foundation.
  • Binding authored lock-file paths to resolved artifacts, and revalidating default/hostname profile evidence, materially strengthens plan provenance.
  • The canonical Hugging Face builder-export test is a good end-to-end regression for nullable secret fields, and the updated golden records make the new lock semantics easy to inspect.

Verdict

Needs changes — Please close the combined-argument secret/owned-flag bypass and reject invalid direct-wheel ports before merge.


This review was generated by an AI assistant.

Signed-off-by: Andre Manoel <amanoel@nvidia.com>
@andreatnvidia

Copy link
Copy Markdown
Contributor Author

@nabinchha Good catches. The combined argument form was bypassing validation because normalization only split on =. It now extracts the leading flag across both = and whitespace, including leading whitespace, so MCP/vLLM secret flags and compiler-owned vLLM flags follow the same checks. Direct wheel URLs also pass through the shared URL validator before wheel-specific validation, which rejects malformed ports early.

@nabinchha nabinchha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick and thorough follow-up, @andreatnvidia!

Summary

The new commit closes the remaining argument-normalization and direct-wheel URL validation gaps. I rechecked the earlier findings as well, and the PR now matches the stated strict authored-config and resolved-plan contract.

Findings

No actionable findings.

What Looks Good

  • The shared _option_flag() helper applies one normalization rule to both stdio MCP and vLLM arguments, including combined values and leading whitespace.
  • Reusing validate_url() gives direct wheel requirements the same host and port guarantees as the other HTTP boundaries while retaining the wheel-specific HTTPS and digest checks.
  • The new regression cases cover the exact bypasses from the previous review. All 171 contract tests pass, and the Slurm source and contract tests pass Ruff and formatting checks.

Verdict

Ship it — the previously requested changes are resolved and this is ready to merge.


This review was generated by an AI assistant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants